package net.lab1024.sa.admin.module.business.ball.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.ball.bo.Lotterykl8;
import net.lab1024.sa.admin.module.business.ball.dao.Lotterykl8Mapper;
import net.lab1024.sa.admin.module.business.ball.service.LotteryKl8Service;
import net.lab1024.sa.admin.module.business.ball.util.BallUtil;
import net.lab1024.sa.admin.module.business.ball.vo.Happy8Vo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class LotteryKl8ServiceImpl  extends ServiceImpl<Lotterykl8Mapper, Lotterykl8> implements LotteryKl8Service {

    private final String kl8Dataurl = "https://www.cz89.com/zst/kl8?year=";

    @Override
    public void updateKl8() throws IOException {
        Document doc = Jsoup.connect(kl8Dataurl+ DateUtil.format(new Date(), "yyyy")).get();
        List<Lotterykl8> ballList = parseKl8(doc);
        saveOrUpdateBatch(ballList);
    }
    List<Integer> years = Lists.newArrayList(2020,2021,2022,2023);

    @Override
    public void getAllData() {
        years.forEach(y ->{
            String newUrl = kl8Dataurl + y;
            Document doc = null;
            try {
                doc = Jsoup.connect(newUrl).get();
                List<Lotterykl8> ballList = parseKl8(doc);
                saveOrUpdateBatch(ballList);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public List<Happy8Vo> kl8Forecast(Integer limit)   {
        LambdaQueryWrapper<Lotterykl8> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Lotterykl8::getPhase).last("limit " + limit);
        List<Lotterykl8> balls = list(queryWrapper);

        if (balls.isEmpty()) {
            System.out.println("没有数据可供预测");
            return null;
        }
        List<Integer> numList = Lists.newArrayList();
        balls.forEach(b -> numList.addAll(b.getNums()));
//        return getMinRepeatNumbers(numList).stream().sorted().collect(Collectors.toList());
        List<Integer> list = BallUtil.countAndSort(numList, 1, 80).subList(0, 20);
        String msg = "福彩快乐8获取过去" + limit + "期内出现次数最少的数字,从小到大排序";
        List<Happy8Vo> voList = Lists.newArrayList();
        voList.add(format(list, msg));
        return voList;
    }

    private Happy8Vo format(List<Integer> list,String msg) {
        Happy8Vo vo = new Happy8Vo();
        vo.setBalls(list.stream().map(i -> String.format("%02d", i)).collect(Collectors.toList()));
        vo.setMsg(msg);
        return vo;
    }
    public static List<Integer> getMinRepeatNumbers(List<Integer> numbers) {
        Map<Integer, Integer> countMap = new HashMap<>();
        for (Integer number : numbers) {
            if (countMap.containsKey(number)) {
                countMap.put(number, countMap.get(number) + 1);
            } else {
                countMap.put(number, 1);
            }
        }

        List<Map.Entry<Integer, Integer>> countList = new ArrayList<>(countMap.entrySet());
        Collections.sort(countList, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o1.getValue() - o2.getValue();
            }
        });

        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < 20 && i < countList.size(); i++) {
            result.add(countList.get(i).getKey());
        }
        return result;
    }


    private int batch = 20;
    private List<Integer> getNum(Elements e, int index){
        List<Integer> list = Lists.newArrayList();
        for (int i = 0; i < batch; i++) {
            list.add(Integer.valueOf(e.get(index * 20 + i).text()));
        }
        return list;
    }
    private List<Lotterykl8> parseKl8(Document doc) {
        List<Lotterykl8> lottryKl8List = Lists.newLinkedList();
        Elements qihaoElements = doc.select("#cpdata > tr:not(.tdbck) > td:first-child ");
        Elements kaijiangElements = doc.select("#cpdata > tr > .chartball20,.chartball01");
        qihaoElements.forEach(qihao ->{
            Lotterykl8 lotterykl8 = new Lotterykl8();
            lotterykl8.setPhase(Integer.parseInt(qihao.text()));
            int index = qihaoElements.indexOf(qihao);
            List<Integer> kl8List = getNum(kaijiangElements, index);
            for (int i = 1; i <= 20; i++) {
                switch (i) {
                    case 1:
                        lotterykl8.setBall1(kl8List.get(0));
                        break;
                    case 2:
                        lotterykl8.setBall2(kl8List.get(1));
                        break;
                    case 3:
                        lotterykl8.setBall3(kl8List.get(2));
                        break;
                    case 4:
                        lotterykl8.setBall4(kl8List.get(3));
                        break;
                    case 5:
                        lotterykl8.setBall5(kl8List.get(4));
                        break;
                    case 6:
                        lotterykl8.setBall6(kl8List.get(5));
                        break;
                    case 7:
                        lotterykl8.setBall7(kl8List.get(6));
                        break;
                    case 8:
                        lotterykl8.setBall8(kl8List.get(7));
                        break;
                    case 9:
                        lotterykl8.setBall9(kl8List.get(8));
                        break;
                    case 10:
                        lotterykl8.setBall10(kl8List.get(9));
                        break;
                    case 11:
                        lotterykl8.setBall11(kl8List.get(10));
                        break;
                    case 12:
                        lotterykl8.setBall12(kl8List.get(11));
                        break;
                    case 13:
                        lotterykl8.setBall13(kl8List.get(12));
                        break;
                    case 14:
                        lotterykl8.setBall14(kl8List.get(13));
                        break;
                    case 15:
                        lotterykl8.setBall15(kl8List.get(14));
                        break;
                    case 16:
                        lotterykl8.setBall16(kl8List.get(15));
                        break;
                    case 17:
                        lotterykl8.setBall17(kl8List.get(16));
                        break;
                    case 18:
                        lotterykl8.setBall18(kl8List.get(17));
                        break;
                    case 19:
                        lotterykl8.setBall19(kl8List.get(18));
                        break;
                    case 20:
                        lotterykl8.setBall20(kl8List.get(19));
                        break;
                    default:
                        break;
                }
            }
            lottryKl8List.add(lotterykl8);
//            lottryKl8List.add(new Lotterykl8(qihao.text(), kaijiangElements.get(qihaoElements.indexOf(qihao)).text()));
        });
        return lottryKl8List;
    }
}
